package cn.zc.tools.security.filter;


import cn.tools.common.adapter.IgnoreTokenConfig;
import cn.tools.common.enums.AuthEnum;
import cn.tools.core.exception.BizException;
import cn.zc.student.entity.VO.RoleVO;
import cn.zc.student.entity.VO.StudentUserVO;
import cn.zc.tools.security.securityEntity.SecurityUser;
import com.alibaba.fastjson.JSONObject;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


/**
 * @author: e
 * @date: 2021/12/27
 * @description: 访问请求前，先进行拦击，并对其身份进行解析，如果解析成功，将身份放入security上下文中，方便securityconfig类进行处理鉴权
 */


public class StudentSecurityFilter extends OncePerRequestFilter{

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String token = request.getHeader(AuthEnum.AUTHORIZATION.getValue());
        if(token == null){

            if(IgnoreTokenConfig.isIgnore(IgnoreTokenConfig.LIST,request.getRequestURI())){
                chain.doFilter(request,response);
                return;
            }
            throw new BizException("未通过网关");

        }
        StudentUserVO userInfoDto = JSONObject.parseObject(token, StudentUserVO.class);

        UsernamePasswordAuthenticationToken authentication = getAuthentication(userInfoDto);
        SecurityContextHolder.getContext().setAuthentication(authentication);

        chain.doFilter(request,response);
    }


    /**
     * 获取token信息
     *
     * @param
     * @param
     * @return 构建鉴权对象
     */
    private UsernamePasswordAuthenticationToken getAuthentication(StudentUserVO userInfo) {
        UserDetails userDetails = loadUserByUsername(userInfo);
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userInfo.getUserName(),null,userDetails.getAuthorities());
        authentication.setDetails(userDetails);
        return authentication;
    }


    /**
     * 构造用户信息
     * @param userInfo
     * @return
     */
    public UserDetails loadUserByUsername(StudentUserVO userInfo){
        List<GrantedAuthority> role = getRole(userInfo);
        SecurityUser user = new SecurityUser(userInfo.getId(),"",userInfo.getUserName()
        ,role,userInfo.getStudentAndClassifyVO(),true,true,true,true);
        return user;
    }

    /**
     *
     * @param userInfo
     * @return 构造权限
     */
    private List<GrantedAuthority> getRole(StudentUserVO userInfo){
        List<GrantedAuthority> auth = new ArrayList<>();

        //设定角色与权限，放入列表
        for (RoleVO role : userInfo.getRole() ){
            auth.add(new SimpleGrantedAuthority("ROLE_"+ role.getUserAuthority()));
        }
        return auth;
    }

}
